(function(root) {
  
  var pc_config = {"iceServers": [{"url": "stun:stun.l.google.com:19302"}]};
  
  var pc = null;
  
  root.createPeerConnection = function() {
    pc = new RTCPeerConnection(pc_config);
    pc.onicecandidate = onIceCandidate;
    pc.onaddstream = onRemoteStreamAdded;

    function onIceCandidate(event) {
      if (event.candidate) {
        // Send candidate to all other peers
        sendMessageToServer({
          type: 'candidate',
          label: event.candidate.sdpMLineIndex,
          id: event.candidate.sdpMid,
          candidate: event.candidate.candidate
        });
      }
    };

    function onRemoteStreamAdded(event) {
      console.log('Remote Stream Added');
      document.querySelector('#remoteVideo').classList.remove('hidden');
      document.querySelector('#remoteVideo').src = URL.createObjectURL(event.stream);
    };
    
    console.log('RTCPeerConnnection created.');
    
    // Add local stream to peer connection
    pc.addStream(root.localStream);
    
    if (root.isCaller) {
      // Create an offer and send it to other peers
      pc.createOffer(function(sessionDescription) {
        pc.setLocalDescription(sessionDescription);  
        sendMessageToServer(sessionDescription);
      });  
    }
  }
  
  root.handleCandidate = function(message) {
    var candidate = new RTCIceCandidate({
      sdpMLineIndex : message.label,
      candidate :     message.candidate
    });
    console.log('Added new candidate');
    pc.addIceCandidate(candidate);  
  }
  
  root.handleOffer = function(message) {   
    // Callee can now create its own peer connection   
    root.createPeerConnection();

    // Offer is only handled by the callee since he did not made an offer
    var remoteDescription = new RTCSessionDescription(message);
    pc.setRemoteDescription(remoteDescription);
    
    // Create an answer and send it to the caller
    pc.createAnswer(function(sessionDescription) {
      pc.setLocalDescription(sessionDescription);    
      sendMessageToServer(sessionDescription);
    });
  }
  
  root.handleAnswer = function(message) {
    // Answer is only handled by the caller since he made an offer
    var remoteDescription = new RTCSessionDescription(message);
    pc.setRemoteDescription(remoteDescription);
  }

  root.handleBye = function() {
    // Other guy just left
    document.querySelector('#remoteVideo').src = '';
    document.querySelector('#remoteVideo').classList.add('hidden');
  }
  
  function sendMessageToServer(message) {
    // Send candidate, answer and offer messages to server which will dispatch them
    var jsonMessage = JSON.stringify(message);
    path = '/message/?from=' + root.clientId + '&type=' + message.type;
    
    var xhr = new XMLHttpRequest();
    xhr.open('POST', path, true);
    xhr.send(jsonMessage);
    console.log('Sending [' + message.type + '] message to server...');
  }
  
})(this);
